package com.lehecai.core.servlet;

import com.lehecai.core.entity.serializer.CorePropDeserializerMap;
import com.lehecai.core.entity.serializer.IPropDeserializer;
import com.lehecai.core.exception.PropDeserializeException;
import com.lehecai.core.exception.RequestParameterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author sunshow
 *
 */
public class ParameterValidateRule {

    protected final static Logger logger = LoggerFactory.getLogger(ParameterValidateRule.class.getName());

	public ParameterValidateRule(String parameter, Class<?> clazz) {
		this(parameter, clazz, null);
	}

    public ParameterValidateRule(String parameter, Class<?> clazz, boolean required) {
        this(parameter, clazz, null, required);
    }

    public ParameterValidateRule(String parameter, Class<?> clazz, IPropDeserializer<?> deserializer) {
        this(parameter, clazz, deserializer, true);
    }

    public ParameterValidateRule(String parameter, Class<?> clazz, IPropDeserializer<?> deserializer, boolean required) {
        this.property = parameter;
        this.parameter = parameter;
        this.clazz = clazz;
        this.deserializer = deserializer;
        this.required = required;
    }
	
	public ParameterValidateRule(String parameter) {
		this(parameter, null);
	}

    public static Map<String, Object> validateRequestParameterResult(ParameterValidateRule[] rules, HttpServletRequest request) throws RequestParameterException {
        if (rules == null) {
            return null;
        }
        Map<String, Object> processedParams = new HashMap<String, Object>();
        for (ParameterValidateRule rule : rules) {
            String property = rule.getProperty();
            String paramValue = request.getParameter(rule.getParameter());
            if (paramValue == null) {
                if (rule.isRequired()) {
                    // 检测是否有此参数
                    throw new RequestParameterException("参数" + rule.getParameter() + "未指定");
                }
                // 未指定，处理下一个参数
                continue;
            }
            IPropDeserializer<?> deserializer = rule.getDeserializer();
            if (deserializer == null) {
                Class<?> clazz = rule.getClazz();
                if (clazz == null) {
                    // 不做处理
                    processedParams.put(property, paramValue);
                    continue;
                }
                deserializer = CorePropDeserializerMap.getDefaultDeserializer(clazz);
                if (deserializer == null) {
                    // 不做处理
                    processedParams.put(property, paramValue);
                    continue;
                }
            }
            try {
                Object paramObj = deserializer.deserialize(paramValue);
                processedParams.put(property, paramObj);
            } catch (PropDeserializeException e) {
                logger.error("解析属性出错", e);
                throw new RequestParameterException("参数" + rule.getParameter() + "解析时出错");
            }
        }
        return processedParams;
    }

	/**
	 * 是否必须的
	 */
	private boolean required;
	
	/**
	 * 校验完成后的属性名
	 */
	private String property;
	/**
	 * 进行校验时使用的参数名
	 */
	private String parameter;

	/**
	 * 要转义的Java类型
	 */
	private Class<?> clazz;
	
	private IPropDeserializer<?> deserializer;

	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		this.property = property;
	}

	public String getParameter() {
		return parameter;
	}

	public void setParameter(String parameter) {
		this.parameter = parameter;
	}

	public Class<?> getClazz() {
		return clazz;
	}

	public void setClazz(Class<?> clazz) {
		this.clazz = clazz;
	}

	public IPropDeserializer<?> getDeserializer() {
		return deserializer;
	}

	public void setDeserializer(IPropDeserializer<?> deserializer) {
		this.deserializer = deserializer;
	}

	public boolean isRequired() {
		return required;
	}

	public void setRequired(boolean required) {
		this.required = required;
	}
	
}
